package com.ics.cmsadmin.modules.basic.service.impl;

import com.ics.cmsadmin.frame.core.annotation.CacheDbMember;
import com.ics.cmsadmin.frame.core.annotation.ClearDbMember;
import com.ics.cmsadmin.frame.core.bean.PageBean;
import com.ics.cmsadmin.frame.core.bean.PageResult;
import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.frame.core.enums.CacheGroupEnum;
import com.ics.cmsadmin.frame.core.enums.LevelEnum;
import com.ics.cmsadmin.frame.core.enums.OrderStatusEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.modules.basic.bean.*;
import com.ics.cmsadmin.modules.basic.dao.CourseDao;
import com.ics.cmsadmin.modules.basic.service.*;
import com.ics.cmsadmin.modules.pub.bean.Course;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by lvsw on 2018-09-01.
 */
@Service
public class CourseServiceImpl implements CourseService {
    @Resource
    private CourseDao courseDao;

    @Autowired
    private OrderService orderService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private CollectionService collectionService;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private UnitService unitService;

    @Autowired
    private TopicService topicService;

    @Autowired
    private CourseTypeService courseTypeService;

    @CacheDbMember(returnClass = CourseBean.class, group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public CourseBean queryById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        return courseDao.queryById(id);
    }

    @CacheDbMember(returnClass = CourseBean.class, group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public PageResult list(CourseBean bean, PageBean page) {
        long count = courseDao.count(bean);
        if (count == 0) {
            return new PageResult();
        }
        page = page == null ? new PageBean() : page;
        List<CourseBean> dataList = courseDao.list(bean, page);
        dataList.forEach(course -> course.setTeachers(teacherService.findByCourseId(course.getId())));
        return PageResult.getPage(count, dataList);
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public boolean insert(CourseBean bean) {
        if (bean == null) {
            return false;
        }
        return courseDao.insert(bean) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public boolean update(String id, CourseBean bean) {
        if (StringUtils.isBlank(id) || bean == null || queryById(id) == null) {
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL, "参数有误");
        }
        CourseBean oldCourse = courseDao.queryById(id);
        BigDecimal oldPrice = getTargetPrice(oldCourse);
        BigDecimal newPrice = getTargetPrice(bean);
        if (oldPrice.compareTo(newPrice) != 0) {
            PageResult pageResult = orderService.list(OrderBean.builder().status(OrderStatusEnum.WAIT.getCode()).courseId(id).build(), new PageBean(1, Integer.MAX_VALUE));
            List<OrderBean> orderList = pageResult.getDataList();
            if (orderList != null && !orderList.isEmpty()) {
                ArrayList<String> removeOrderIds = new ArrayList<>();
                for (OrderBean order : orderList) {
                    removeOrderIds.add(order.getId());
                }
                if (removeOrderIds.size() > 0) {
                    orderService.batchSoftRemove(removeOrderIds);
                }
            }

        }
        return courseDao.update(id, bean) == 1;
    }

    private BigDecimal getTargetPrice(CourseBean courseBean) {
        BigDecimal targetPrice = courseBean.getDiscountPrice();
        if (null == targetPrice || targetPrice.compareTo(BigDecimal.ZERO) == 0) {
            targetPrice = courseBean.getPrice();
            if (null == targetPrice) {
                targetPrice = BigDecimal.ZERO;
            }
        }
        return targetPrice;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public boolean delete(String id) {
        if (StringUtils.isBlank(id) || queryById(id) == null) {
            throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL, "参数有误");
        }
        return courseDao.delete(id) == 1;
    }

    @CacheDbMember(returnClass = CourseBean.class, group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public List<CourseBean> listAllCourseBySubjectId(String subjectId) {
        return courseDao.listAllCourseBySubjectId(subjectId);
    }

    @Override
    public PageResult list(String userId, CourseBean bean, PageBean page) {
        PageResult pageResult = list(bean, page);
        List<CourseBean> dataList = (List<CourseBean>) pageResult.getDataList();
        dataList.forEach(course -> {
            course.setHasBought(orderService.getPurchaseStatus(userId, course.getId()));
        });
        return pageResult;
    }

    @Override
    public PageResult purchased(String userId, PageBean page) {
        PageResult pageResult;
        pageResult = orderService.list(OrderBean.builder().userId(userId).status(OrderStatusEnum.SUCCESS.getCode()).build(), page);
        List<OrderBean> orderList = (List<OrderBean>) pageResult.getDataList();
        if (CollectionUtils.isEmpty(orderList)) {
            pageResult.setDataList(new ArrayList<Course>());
            return pageResult;
        }
        List<String> courseIds = orderList.stream().map(OrderBean::getCourseId).collect(Collectors.toList());
        List<CourseBean> courseList = courseDao.findByIdsIn(courseIds);
        courseList.forEach(courseBean -> courseBean.setTeachers(teacherService.findByCourseId(courseBean.getId())));
        pageResult.setDataList(courseList);
        return pageResult;
    }

    @Override
    public CourseBean courseDetail(String userId, String courseId) {
        CourseBean courseBean = courseDao.queryById(courseId);
        boolean bought = orderService.getPurchaseStatus(userId, courseId);
        courseBean.setHasBought(bought);
        Boolean liked = likeService.select(new Like(userId, LevelEnum.course, courseId));
        courseBean.setLiked(liked);
        courseBean.setThumbUpCount(likeService.queryTotal(LevelEnum.course, courseId));
        Boolean collected = collectionService.select(new Collect(userId, LevelEnum.course, courseId));
        courseBean.setCollected(collected);
        courseBean.setCollectCount(collectionService.queryTotal(LevelEnum.course, courseId));
        courseBean.setTeachers(teacherService.findByCourseId(courseId));

        /* special vip start **/
        StudentBean studentBean = studentService.queryById(userId);
        if (studentBean != null) {
            Boolean specialVip = studentBean.getSpecialVip();
            if (specialVip) {
                courseBean.setPrice(new BigDecimal(1.0));
                courseBean.setDiscountPrice(new BigDecimal(0));
            }
        }
        /* special vip end **/


        return courseBean;
    }

    @Override
    public CourseBean courseAllDetail(String userId, String courseId) {
        CourseBean courseBean = courseDetail(userId, courseId);
        List<UnitBean> unitList = unitService.listAllUnitByCourseId(courseId);
        unitList.forEach(unit -> {
            List<TopicBean> topicList = topicService.listDetail(userId, unit.getId());
            unit.setTopicList(topicList);
        });
        courseBean.setUnitList(unitList);
        return courseBean;
    }

    /**
     * 记录课程点击量
     *
     * @param courseId
     */
    public void increaseViewNum(String courseId) {
        CourseBean course = courseDao.queryById(courseId);
        Integer clickNumber = course.getClickNumber();
        clickNumber = clickNumber != null ? clickNumber : 0;
        course.setClickNumber(clickNumber + 1);
        courseDao.update(courseId, course);
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public boolean bindCourseType(String courseId, String courseTypeId) {
        int effectLine = 0;
        try {
            effectLine = courseDao.bindCourseType(courseId, courseTypeId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return effectLine == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public boolean unbindCourseType(String courseId, String courseTypeId) {
        return courseDao.unbindCourseType(courseId, courseTypeId) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_COURSE)
    @Override
    public boolean bulkUnbindCourseType(List<String> ids, String courseTypeId) {
        return courseDao.bulkUnbindCourseType(ids, courseTypeId) != 0;
    }

    @Override
    public List<CourseSection> listCourseSections() {
        PageResult courseTypePage = courseTypeService.list(CourseTypeBean.builder().isActive(true).build(), new PageBean(1, Integer.MAX_VALUE));
        List<CourseTypeBean> courseTypeList = (List<CourseTypeBean>) courseTypePage.getDataList();
        List<CourseSection> courseSections = new ArrayList<>();
        courseTypeList.forEach(courseType -> {
            CourseSection section = new CourseSection();
            CourseSection.Header header = new CourseSection.Header();
            List<CourseBean> courseList = courseDao.list(CourseBean.builder().courseTypeId(courseType.getId()).isActive(true).build(), new PageBean(1, 3));
            section.setBody(courseList);
            header.setTitle(courseType.getName());
            header.setDescription(courseType.getDescription());
            section.setHeader(header);
            courseSections.add(section);
        });
        return courseSections;
    }
}
